/*
 * Copyright (C) 2019 Peng fei Pan <panpfpanpf@outlook.me>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package me.panpf.sketch.datasource;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import me.panpf.sketch.cache.BitmapPool;
import me.panpf.sketch.decode.ImageAttrs;
import me.panpf.sketch.decode.NotFoundGifLibraryException;
import me.panpf.sketch.request.ImageFrom;
import me.panpf.sketch.util.SketchUtils;
import me.panpf.sketch.util.TextUtils;
import ohos.app.Context;
import ohos.global.resource.RawFileDescriptor;
import ohos.global.resource.RawFileEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import me.panpf.sketch.Gif;

/**
 * 用于读取来自 asset 的图片
 */
public class AssetsDataSource implements DataSource {

    @NotNull
    private Context context;
    @NotNull
    private String assetsFilePath;
    private long length = -1;

    public AssetsDataSource(@NotNull Context context, @NotNull String assetsFilePath) {
        this.context = context;
        this.assetsFilePath = assetsFilePath;
    }

    @NotNull
    @Override
    public InputStream getInputStream() throws IOException {
        RawFileEntry rawFileEntry = context.getResourceManager().getRawFileEntry(assetsFilePath);
        return rawFileEntry.openRawFile();
    }

    @Override
    public synchronized long getLength() throws IOException {
        if (length >= 0) {
            return length;
        }

//        AssetFileDescriptor fileDescriptor = null;
        RawFileDescriptor fileDescriptor = null;
        try {
            fileDescriptor = context.getResourceManager().getRawFileEntry(assetsFilePath).openRawFileDescriptor();
            length = fileDescriptor.getFileSize();
        } finally {
            SketchUtils.close(fileDescriptor);
        }
        return length;
    }

    @Override
    public File getFile(@Nullable File outDir, @Nullable String outName) throws IOException {
        if (outDir == null) {
            return null;
        }

        if (!outDir.exists() && !outDir.getParentFile().mkdirs()) {
            return null;
        }

        File outFile;
        if (!TextUtils.isEmpty(outName)) {
            outFile = new File(outDir, outName);
        } else {
            outFile = new File(outDir, SketchUtils.generatorTempFileName(this, assetsFilePath));
        }
        InputStream inputStream = getInputStream();

        OutputStream outputStream;
        try {
            outputStream = new FileOutputStream(outFile);
        } catch (IOException e) {
            SketchUtils.close(inputStream);
            throw e;
        }

        byte[] data = new byte[1024];
        int length;
        try {
            while ((length = inputStream.read(data)) != -1) {
                outputStream.write(data, 0, length);
            }
        } finally {
            SketchUtils.close(outputStream);
            SketchUtils.close(inputStream);
        }

        return outFile;
    }

    @NotNull
    @Override
    public ImageFrom getImageFrom() {
        return ImageFrom.LOCAL;
    }

    @NotNull
    @Override
    public Gif makeGifDrawable(@NotNull String key, @NotNull String uri, @NotNull ImageAttrs imageAttrs,
                               @NotNull BitmapPool bitmapPool) throws IOException, NotFoundGifLibraryException {
//        AssetManager assetManager = context.getAssets();
//        ResourceManager resourceManager = context.getResourceManager();
//        return SketchGifFactory.createGifDrawable(key, uri, imageAttrs, getImageFrom(), bitmapPool, context, assetsFilePath);
//        return null;
        return new Gif(context, assetsFilePath);
    }
}
